package com.lfy.fyadmin.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lfy.fyadmin.entity.User;
import com.lfy.fyadmin.entity.UserRole;
import com.lfy.fyadmin.entity.Role;
import com.lfy.fyadmin.entity.UserGroup;
import com.lfy.fyadmin.entity.Group;
import com.lfy.fyadmin.service.UserService;
import com.lfy.fyadmin.service.UserRoleService;
import com.lfy.fyadmin.service.RoleService;
import com.lfy.fyadmin.service.UserGroupService;
import com.lfy.fyadmin.service.GroupService;
import com.lfy.fyadmin.mapper.UserMapper;
import com.lfy.fyadmin.vo.UserVO;
import com.lfy.fyadmin.dto.UserUpdateRequest;
import com.lfy.fyadmin.dto.UserQueryRequest;
import com.lfy.fyadmin.dto.CurrentUserPasswordChangeRequest;
import com.lfy.fyadmin.dto.AdminResetPasswordRequest;
import com.lfy.fyadmin.util.PasswordUtil;
import com.lfy.fyadmin.util.PermissionCheckUtil;
import cn.dev33.satoken.stp.StpUtil;

import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
* @author 53409
* @description 针对表【user(用户表)】的数据库操作Service实现
* @createDate 2025-07-23 21:51:27
*/
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User>
    implements UserService{

    @Autowired
    private UserRoleService userRoleService;

    @Autowired
    private RoleService roleService;

    @Autowired
    private UserGroupService userGroupService;

    @Autowired
    private GroupService groupService;

    @Autowired
    private PermissionCheckUtil permissionCheckUtil;

    @Override
    public UserVO getUserWithRolesAndGroups(Long id) {
        // 查询用户信息
        User user = this.getById(id);
        if (user == null) {
            return null;
        }

        // 查询用户角色关联信息
        List<UserRole> userRoles = userRoleService.lambdaQuery()
                .eq(UserRole::getUserId, id)
                .list();

        // 查询用户角色信息
        List<Role> roles = userRoles.stream()
                .map(userRole -> roleService.getById(userRole.getRoleId()))
                .collect(Collectors.toList());

        // 查询用户分组关联信息
        List<UserGroup> userGroups = userGroupService.lambdaQuery()
                .eq(UserGroup::getUserId, id)
                .list();

        // 查询用户分组信息
        List<Group> groups = userGroups.stream()
                .map(userGroup -> groupService.getById(userGroup.getGroupId()))
                .collect(Collectors.toList());

        // 封装VO
        UserVO userVO = new UserVO();
        userVO.setUser(user);
        userVO.setRoles(roles);
        userVO.setGroups(groups);

        return userVO;
    }

    @Override
    public boolean updateSelective(User user) {
        return this.baseMapper.updateSelective(user) > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateUserWithRolesAndGroups(UserUpdateRequest request) {
        // 1. 更新用户基本信息
        User user = new User();
        user.setId(request.getId());
        user.setUsername(request.getUsername());
        //password 的规则
        if (StringUtils.hasText(request.getPassword())) {
            String salt = PasswordUtil.generateSalt();
            String password = PasswordUtil.encryptPassword(request.getPassword(), salt);
            user.setSalt(salt);
            user.setPassword(password);
        }

        user.setRealName(request.getRealName());
        user.setAvatar(request.getAvatar());
        user.setEmail(request.getEmail());
        user.setMobile(request.getMobile());
        user.setStatus(request.getStatus());
        user.setDeleted(request.getDeleted());

        if (request == null || request.getId() == null) {
            //新增用户；如果提交密码，密码单独处理
            this.save(user);
        }



        boolean userUpdated = this.updateSelective(user);
        if (!userUpdated) {
            return false;
        }

        // 2. 处理用户角色关联关系
        updateUserRoles(user.getId(), request.getRoleIds());

        // 3. 处理用户分组关联关系
        updateUserGroups(user.getId(), request.getGroupIds());

        return true;
    }

    /**
     * 更新用户角色关联关系
     * @param userId 用户ID
     * @param roleIds 新的角色ID列表
     */
    private void updateUserRoles(Long userId, List<Long> roleIds) {
        // 删除原有的用户角色关联关系
        userRoleService.lambdaUpdate()
                .eq(UserRole::getUserId, userId)
                .remove();

        // 添加新的用户角色关联关系
        if (!CollectionUtils.isEmpty(roleIds)) {
            List<UserRole> userRoles = roleIds.stream()
                    .map(roleId -> {
                        UserRole userRole = new UserRole();
                        userRole.setUserId(userId);
                        userRole.setRoleId(roleId);
                        userRole.setCreateTime(new Date());
                        return userRole;
                    })
                    .collect(Collectors.toList());
            
            userRoleService.saveBatch(userRoles);
        }
    }

    /**
     * 更新用户分组关联关系
     * @param userId 用户ID
     * @param groupIds 新的分组ID列表
     */
    private void updateUserGroups(Long userId, List<Long> groupIds) {
        // 删除原有的用户分组关联关系
        userGroupService.lambdaUpdate()
                .eq(UserGroup::getUserId, userId)
                .remove();

        // 添加新的用户分组关联关系
        if (!CollectionUtils.isEmpty(groupIds)) {
            List<UserGroup> userGroups = groupIds.stream()
                    .map(groupId -> {
                        UserGroup userGroup = new UserGroup();
                        userGroup.setUserId(userId);
                        userGroup.setGroupId(groupId);
                        userGroup.setCreateTime(new Date());
                        return userGroup;
                    })
                    .collect(Collectors.toList());
            
            userGroupService.saveBatch(userGroups);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean changeCurrentUserPassword(CurrentUserPasswordChangeRequest request) {
        if (request == null) {
            throw new IllegalArgumentException("请求参数不能为空");
        }

        // 1. 验证新密码和确认密码是否一致
        if (!request.getNewPassword().equals(request.getConfirmPassword())) {
            throw new IllegalArgumentException("新密码和确认密码不一致");
        }

        // 2. 验证新密码强度
        if (!PasswordUtil.isPasswordStrong(request.getNewPassword())) {
            throw new IllegalArgumentException("新密码强度不够，必须包含数字和字母，长度6-20位");
        }

        // 3. 获取当前登录用户ID
        Long currentUserId = permissionCheckUtil.getCurrentUserId();

        // 4. 查询当前用户信息
        User user = this.getById(currentUserId);
        if (user == null) {
            throw new IllegalArgumentException("用户不存在");
        }

        // 5. 验证原密码是否正确
        if (!PasswordUtil.verifyPassword(request.getOldPassword(), user.getPassword(), user.getSalt())) {
            throw new IllegalArgumentException("原密码错误");
        }

        // 6. 检查新密码是否与原密码相同
        if (PasswordUtil.isSamePassword(request.getOldPassword(), request.getNewPassword())) {
            throw new IllegalArgumentException("新密码不能与原密码相同");
        }

        // 7. 生成新的盐值和加密新密码
        String newSalt = PasswordUtil.generateSalt();
        String encryptedNewPassword = PasswordUtil.encryptPassword(request.getNewPassword(), newSalt);

        // 8. 更新用户密码和盐值
        User updateUser = new User();
        updateUser.setId(currentUserId);
        updateUser.setPassword(encryptedNewPassword);
        updateUser.setSalt(newSalt);

        return this.updateSelective(updateUser);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean adminResetPassword(AdminResetPasswordRequest request) {
        if (request == null) {
            throw new IllegalArgumentException("请求参数不能为空");
        }

        // 1. 验证用户登录状态
        if (!permissionCheckUtil.isCurrentUserLogin()) {
            throw new IllegalArgumentException("用户未登录");
        }

        // 2. 验证管理员权限
        if (!permissionCheckUtil.isCurrentUserAdmin()) {
            throw new IllegalArgumentException("权限不足，只有管理员可以重置用户密码");
        }

        // 2. 验证新密码和确认密码是否一致
        if (!request.getNewPassword().equals(request.getConfirmPassword())) {
            throw new IllegalArgumentException("新密码和确认密码不一致");
        }

        // 3. 验证新密码强度
        if (!PasswordUtil.isPasswordStrong(request.getNewPassword())) {
            throw new IllegalArgumentException("新密码强度不够，必须包含数字和字母，长度6-20位");
        }

        // 4. 查询目标用户信息
        User targetUser = this.getById(request.getTargetUserId());
        if (targetUser == null) {
            throw new IllegalArgumentException("目标用户不存在");
        }

        // 5. 生成新的盐值和加密新密码
        String newSalt = PasswordUtil.generateSalt();
        String encryptedNewPassword = PasswordUtil.encryptPassword(request.getNewPassword(), newSalt);

        // 6. 更新目标用户密码和盐值
        User updateUser = new User();
        updateUser.setId(request.getTargetUserId());
        updateUser.setPassword(encryptedNewPassword);
        updateUser.setSalt(newSalt);

        return this.updateSelective(updateUser);
    }

    @Override
    public IPage<User> pageUsers(UserQueryRequest request) {
        // 创建分页对象
        Page<User> page = new Page<>(request.getPageNum(), request.getPageSize());
        
        // 构建查询条件
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        
        // 关键词搜索：用户名、邮箱、手机号模糊查询
        if (StringUtils.hasText(request.getKeyword())) {
            queryWrapper.and(wrapper -> wrapper
                .like("username", request.getKeyword())
                .or()
                .like("email", request.getKeyword())
                .or()
                .like("mobile", request.getKeyword())
            );
        }
        
        // 状态查询
        if (request.getStatus() != null) {
            queryWrapper.eq("status", request.getStatus());
        }
        
        // 角色ID查询 - 需要关联查询用户角色表
        if (request.getRoleId() != null) {
            queryWrapper.exists("SELECT 1 FROM sys_user_role ur WHERE ur.user_id = sys_user.id AND ur.role_id = {0}", request.getRoleId());
        }
        
        // 默认按创建时间倒序排列
        queryWrapper.orderByDesc("create_time");
        
        return this.page(page, queryWrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteUserWithRelations(Long userId) {
        try {
            // 1. 删除用户角色关联关系
            userRoleService.lambdaUpdate()
                    .eq(UserRole::getUserId, userId)
                    .remove();

            // 2. 删除用户分组关联关系
            userGroupService.lambdaUpdate()
                    .eq(UserGroup::getUserId, userId)
                    .remove();

            // 3. 删除用户本身
            return this.removeById(userId);
        } catch (Exception e) {
            throw new RuntimeException("删除用户及其关联资源失败", e);
        }
    }
}




